#!/bin/bash -norc
#
# Copyright (c) 2004 Nikolai Joukov and Erez Zadok
# Copyright (c) 2004 SUNY at Stony Brook
#
# This script splits raw txt stats file into per op and total csv and txt files.
# In addition, it checks files consistency for debugging purposes.
#
# usage: split_stat.sh [cowts]
#	c - check values for consistency
#	o - overwrite files
#	w - generate files with approximated buckets delay impact
#	t - generate t files
#	s - generate csv files
#
# All TOTALS* files have the same format:
#	OP_* TOTAL_NUMBER_OF_OPS TOTAL_NUMBER_OF_CYCLES SOME_ARRAY[]
#
# TODO:
#  Rewrite in perl for better performance
#

# Generate TOTALS files
gen_totals() {
	[ "$CURRENT_OP" != "OP_UNKNOWN" ] &&
		echo $CURRENT_OP $CURRENT_OP_NUM $CURRENT_OP_CYCLES ${BUCKET_OPS[@]} >> TOTALS.txt &&
			[ "$OPT_s" != "" ] &&
				echo $CURRENT_OP $CURRENT_OP_NUM $CURRENT_OP_CYCLES ${BUCKET_OPS[@]} | sed 's/^[ \t]*/"/;s/[ \t][ \t]*/","/g;s/[ \t]*$/"/' >> TOTALS.csv &&
					sed 's/^[ \t]*/"/;s/[ \t][ \t]*/","/g;s/[ \t]*$/"/' < "$CURRENT_OP.txt" > "$CURRENT_OP.csv" &&
		[ "$OPT_w" != "" ] &&
			echo $CURRENT_OP $CURRENT_OP_NUM $CURRENT_OP_CYCLES ${BUCKET_OPS_W[@]} >> TOTALS-W.txt &&
				[ "$OPT_s" != "" ] &&
					sed 's/^[ \t]*/"/;s/[ \t][ \t]*/","/g;s/[ \t]*$/"/' < "$CURRENT_OP-W.txt" > "$CURRENT_OP-W.csv" &&
						echo $CURRENT_OP $CURRENT_OP_NUM $CURRENT_OP_CYCLES ${BUCKET_OPS_W[@]} | sed 's/^[ \t]*/"/;s/[ \t][ \t]*/","/g;s/[ \t]*$/"/' >> TOTALS-W.csv
}

# Check all values if 'c' option is specified on commandline:
# (Our estimation is +- 33% accurate)
check_stats() {
	[ "$OPT_c" != "" ] && [ "$OPT_w" != "" ] && [ "$CURRENT_OP" != "OP_UNKNOWN" ] &&
		CHECK_OP_CYCLES=$((`echo ${BUCKET_OPS_W[@]} | sed 's/^[ \t]*//;s/[ \t]*$//;s/[ \t][ \t]*/+/g'`)) &&
		[ $(($CHECK_OP_CYCLES*4/3)) -le $CURRENT_OP_CYCLES -o $(($CHECK_OP_CYCLES*2/3)) -ge $CURRENT_OP_CYCLES ] &&
		echo "WARNING: operations delay mismatch: $CHECK_OP_CYCLES != $CURRENT_OP_CYCLES"
	[ "$OPT_c" != "" ] && [ "$CURRENT_OP" != "OP_UNKNOWN" ] &&
		CHECK_OP_NUM=$((`echo ${BUCKET_OPS[@]} | sed 's/^[ \t]*//;s/[ \t]*$//;s/[ \t][ \t]*/+/g'`)) &&
		[ $CHECK_OP_NUM -ne $CURRENT_OP_NUM ] && 
		echo "WARNING: operations count mismatch: $CHECK_OP_NUM != $CURRENT_OP_NUM"
}

OPT_c=`echo $1 | sed -n '/c/p'`
OPT_o=`echo $1 | sed -n '/o/p'`
OPT_w=`echo $1 | sed -n '/w/p'`
OPT_t=`echo $1 | sed -n '/t/p'`
OPT_s=`echo $1 | sed -n '/s/p'`

[ "$OPT_o" == "" ] && [ -a TOTALS.txt ] &&
	echo "File TOTALS.txt exists. Delete it or specify 'o' option if you want to overwrite all files." && exit

# Delete output files
[ -a TOTALS.txt ] && rm TOTALS.txt
[ -a TOTALS.csv ] && rm TOTALS.csv
[ -a TOTALS-W.txt ] && rm TOTALS-W.txt
[ -a TOTALS-W.csv ] && rm TOTALS-W.csv
[ -a TOTALS-T.txt ] && rm TOTALS-T.txt
[ -a TOTALS-TW.txt ] && rm TOTALS-TW.txt
[ -a TOTALS-T.csv ] && rm TOTALS-T.csv
[ -a TOTALS-TW.csv ] && rm TOTALS-TW.csv

EMPTY_LINE=" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
CURRENT_OP=OP_UNKNOWN
read LINE
EOF=$?

# Check input data
[ "`echo $LINE | sed -n '/^OP_/p'`" == "" ] && echo "Invalid input" && exit

until [ "$LINE" == "" ]; do
	if [ "`echo $LINE | sed -n '/^OP_/p'`" == "" ]; then
		[ "$LINE" != "-" ] && echo $LINE >> "$CURRENT_OP.txt" &&
			[ "$OPT_t" != "" ] &&
				echo -n " $((`echo $LINE | sed 's/^[ \t]*//;s/[ \t]*$//;s/[ \t][ \t]*/+/g'`))" >> "TOTALS-T.txt"
		[ "$LINE" == "-" ] && echo $EMPTY_LINE >> "$CURRENT_OP.txt" &&
			[ "$OPT_t" != "" ] &&
				echo -n " 0" >> "TOTALS-T.txt"
		LINE_W=
		W=32
		BUCKETS_NUM=0
		[ "$LINE" != "-" ] && until [ "$LINE" == "" ]; do
			CURRENT_BUCKET=`echo $LINE | sed 's/^[ \t]*//;s/[ \t]/$/;s/$.*$//'`
			BUCKET_OPS[$BUCKETS_NUM]=$((${BUCKET_OPS[$BUCKETS_NUM]}+$CURRENT_BUCKET))
			[ "$OPT_w" != "" ] &&
				CURRENT_BUCKET_W=$(($CURRENT_BUCKET*$W*3/4)) &&
				BUCKET_OPS_W[$BUCKETS_NUM]=$((${BUCKET_OPS_W[$BUCKETS_NUM]}+$CURRENT_BUCKET_W)) &&
				LINE_W=`echo $LINE_W $CURRENT_BUCKET_W` &&
				W=$(($W*2))
			BUCKETS_NUM=$(($BUCKETS_NUM+1))
			LINE=`echo $LINE | sed 's/[ \t]*[0-9]*//'`
		done;
		# Create files with approximated delay impact of individual buckets if 'w' option is given.
		if [ "$OPT_w" != "" ]; then
			[ "$LINE" != "-" ] && echo $LINE_W >> "$CURRENT_OP-W.txt"
			[ "$LINE" == "-" ] && echo $EMPTY_LINE >> "$CURRENT_OP-W.txt"
			if [ "$OPT_t" != "" ]; then
				[ "$LINE" != "-" ] && echo -n " $((`echo $LINE_W | sed 's/^[ \t]*//;s/[ \t]*$//;s/[ \t][ \t]*/+/g'`))" >> "TOTALS-TW.txt"
				[ "$LINE" == "-" ] && echo -n " 0" >> "TOTALS-TW.txt"
			fi;
		fi;
		echo -n "."
	else
		check_stats;
		gen_totals;
		[ "$CURRENT_OP" != "OP_UNKNOWN" ] &&
			[ "$OPT_t" != "" ] && echo >> "TOTALS-T.txt" &&
			[ "$OPT_w" != "" ] && echo >> "TOTALS-TW.txt"
		CURRENT_OP=`echo $LINE | sed 's/[ \t]*[0-9]*[ \t][0-9]*$//'`
		CURRENT_OP_NUM=`echo $LINE | sed 's/^OP_[a-Z_]*[ \t]*//;s/[ \t]*[0-9]*$//'`
		CURRENT_OP_CYCLES=`echo $LINE | sed 's/^OP_[a-Z_]*[ \t]*[0-9]*[ \t]//'`
		
		echo
		echo "Processing $CURRENT_OP "
		
		# Delete output files
		[ -a "$CURRENT_OP.txt" ] && rm "$CURRENT_OP.txt"
		[ -a "$CURRENT_OP.csv" ] && rm "$CURRENT_OP.csv"
		[ "$OPT_w" != "" ] && [ -a "$CURRENT_OP-W.txt" ] && rm "$CURRENT_OP-W.txt"
		[ "$OPT_w" != "" ] && [ -a "$CURRENT_OP-W.csv" ] && rm "$CURRENT_OP-W.csv"
		
		# Start new lines in timeline projection files		
		[ "$OPT_t" != "" ] && echo -n "$CURRENT_OP $CURRENT_OP_NUM $CURRENT_OP_CYCLES" >> "TOTALS-T.txt" &&
		[ "$OPT_w" != "" ] && echo -n "$CURRENT_OP $CURRENT_OP_NUM $CURRENT_OP_CYCLES" >> "TOTALS-TW.txt"
		
		BUCKET_OPS=()
		BUCKET_OPS_W=()
	fi;
	if [ $EOF -eq 1 ]; then
		LINE=""
	else
		read LINE
		EOF=$?
	fi;
done;

check_stats;
gen_totals;

# generate missing csvs
[ "$OPT_t" != "" ] && [ "$OPT_s" != "" ] && 
	sed 's/^[ \t]*/"/;s/[ \t][ \t]*/","/g;s/[ \t]*$/"/' < "TOTALS-T.txt" > "TOTALS-T.csv" &&
	[ "$OPT_w" != "" ] &&
		sed 's/^[ \t]*/"/;s/[ \t][ \t]*/","/g;s/[ \t]*$/"/' < "TOTALS-TW.txt" > "TOTALS-TW.csv"

# generate .cvsignore
if [ ! -e .cvsignore ] ; then
	echo -e "OP_*\nTOTAL*" > .cvsignore
fi
